<template>
  <div>
    <tdt-map
      ref="tdtMap"
      style="width: 100%; height: 800px"
      :center="state.center"
      :zoom="state.zoom"
      :loadConfig="loadConfig"
      @init="mapInit"
    >
      <!-- Marker 聚合 -->
      <tdt-marker-clusterer :markers="markers" :styles="styles" />

      <!-- 高亮省份（GeoJSON 填充） -->
      <tdt-polygon
        v-for="(p, i) in provincePolygons"
        :key="'poly-' + i"
        :path="p.path"
        :strokeColor="'#ff0000'"
        :fillColor="'rgba(255,0,0,0.2)'"
        :strokeWeight="2"
      />

      <!-- 省份名称标签 -->
      <tdt-label
        v-for="(province, i) in provinceLabels"
        :key="'label-' + i"
        :position="province.position"
        :content="province.name"
        :offset="[0, -10]"
        :color="'#0000ff'"
        :fontSize="14"
      />

      <!-- 中心点 -->
      <tdt-marker
        :position="state.center"
        icon="https://soullyoko.github.io/vue-tianditu/marker_red.png"
      />

      <!-- 信息窗 -->
      <tdt-infowindow v-model:target="target" :content="content" />
    </tdt-map>
  </div>
</template>

<script setup>
import { reactive, ref } from 'vue'
import 'vue-tianditu/lib/style.css'
import chinaGeoJson from '@/assets/chinas.json'
import pointInPolygon from 'point-in-polygon'

// 地图初始化配置
const loadConfig = { v: '4.0', tk: '8362ba89b7bfb71c70cac2ef0390132a' }

const state = reactive({
  center: [105, 35], // 地图中心点（全国）
  zoom: 5,
})

const target = ref(null)
const content = ref('')
const map = ref(null)

const defaultIcon = 'https://soullyoko.github.io/vue-tianditu/marker_red.png'
const activeIcon = 'https://soullyoko.github.io/vue-tianditu/marker_blue.png'

// 聚合样式
const styles = ref([
  {
    url: 'https://api.tianditu.gov.cn/img/map/markers/b1.png',
    size: [32, 32],
    offset: [-16, -32],
    textColor: '#fff',
    textSize: 12,
    range: [0, 50],
  },
  {
    url: 'https://api.tianditu.gov.cn/img/map/markers/b2.png',
    size: [48, 48],
    offset: [-24, -48],
    textColor: '#FF0000',
    textSize: 14,
    range: [50, 200],
  },
  {
    url: 'https://api.tianditu.gov.cn/img/map/markers/b3.png',
    size: [64, 64],
    offset: [-32, -64],
    textColor: '#000',
    textSize: 16,
    range: [200, 10000],
  },
])

// 判断点是否在中国 GeoJSON 范围内
function isPointInChina(lng, lat) {
  if (!chinaGeoJson?.features) return false
  for (const province of chinaGeoJson.features) {
    const { type, coordinates } = province.geometry
    if (type === 'Polygon') {
      for (const ring of coordinates) {
        if (pointInPolygon([lng, lat], ring)) return true
      }
    } else if (type === 'MultiPolygon') {
      for (const polygon of coordinates) {
        for (const ring of polygon) {
          if (pointInPolygon([lng, lat], ring)) return true
        }
      }
    }
  }
  return false
}

// 随机生成点位（中国范围内）
function generateChinaPoints(count = 10000) {
  const points = []
  while (points.length < count) {
    const lng = 73 + Math.random() * (135 - 73)
    const lat = 18 + Math.random() * (54 - 18)
    if (isPointInChina(lng, lat)) {
      const id = points.length
      points.push({
        position: [lng, lat],
        icon: defaultIcon,
        extData: { id },
        events: {
          click(e) {
            e.target.setIcon(activeIcon)
            content.value = `你点击了点位：${id}`
            target.value = e.target
          },
        },
      })
    }
  }
  return points
}

const markers = ref(generateChinaPoints(10000))

const provincePolygons = ref([])
const provinceLabels = ref([])

function getPolygonCenter(ring) {
  let lngSum = 0
  let latSum = 0
  ring.forEach(([lng, lat]) => {
    lngSum += lng
    latSum += lat
  })
  const len = ring.length
  return [lngSum / len, latSum / len]
}

function drawAllProvinces() {
  if (!chinaGeoJson?.features) return

  const polygons = []
  const labels = []

  for (const province of chinaGeoJson.features) {
    const { type, coordinates } = province.geometry
    const name = province.properties.name

    if (type === 'Polygon') {
      coordinates.forEach((ring, idx) => {
        const path = ring.map((coord) => ({ lng: coord[0], lat: coord[1] }))
        polygons.push({ path })
        if (idx === 0) {
          const [lng, lat] = getPolygonCenter(ring)
          labels.push({ name, position: [lng, lat] })
        }
      })
    } else if (type === 'MultiPolygon') {
      coordinates.forEach((polygon, pidx) => {
        polygon.forEach((ring, ridx) => {
          const path = ring.map((coord) => ({ lng: coord[0], lat: coord[1] }))
          polygons.push({ path })
          if (pidx === 0 && ridx === 0) {
            const [lng, lat] = getPolygonCenter(ring)
            labels.push({ name, position: [lng, lat] })
          }
        })
      })
    }
  }

  provincePolygons.value = polygons
  provinceLabels.value = labels
}

function mapInit(m) {
  map.value = m
  drawAllProvinces()
}
</script>
